import {commonInstance} from '@/request/index'
// ******************************四种通用的查询方法*********************
// 通用get请求
function httpGet (url, params, config = {}) {
  return commonInstance.get(url, {params, ...config})
}

// 通用post请求
function httpPost (url, data, config = {}) {
  return commonInstance.post(url, data, config)
}

// 通用put请求
function httpPut (url, data, config = {}) {
  return commonInstance.put(url, data, config)
}

// 通用delete请求,传递的参数为String或String数组
function httpDelete (url, params, config = {}) {
  // 项目中统一处理为字符串
  const $params = params.toString()
  return commonInstance.delete(url + '/' + $params, config)
}

// 通用的post请求(请求体为form表单)
function httpPostForm (url, params, config = {}) {
  return commonInstance.postForm(url, params, config)
}

// 通用的put请求(请求体为form表单)
function httpPutForm (url, params, config = {}) {
  return commonInstance.putForm(url, params, config)
}

// *****************************业务上的通用请求接口********************************

const queryUrl = '/query'
const listUrl = '/list'
const getUrl = '/get'
const getByIdUrl = '/getById'
const insertUrl = '/insert'
const listByIdsUrl = '/listByIds'
const updateByIdUrl = '/updateById'
const deleteByIdsUrl = '/deleteByIds'
const listVoUrl = '/listVo'

/**
 * 通用的分页查询接口
 * @param baseUrl
 * @param params
 * @return {Promise<AxiosResponse<any>>}
 */
function query (baseUrl, params) {
  const url = baseUrl + queryUrl
  return httpGet(url, params)
}

/**
 * 通用的根据条件获取一条数据接口
 * @param baseUrl
 * @param params
 * @return {Promise<AxiosResponse<any>>}
 */
function get (baseUrl, params) {
  const url = baseUrl + getUrl
  return httpGet(url, params)
}

/**
 * 通用的根据ID查找接口
 * @param {String} baseUrl
 * @param {String} params ID
 * @return {Promise<AxiosResponse<any>>}
 */
function getById (baseUrl, params) {
  const url = baseUrl + getByIdUrl
  return httpGet(url, {id: params})
}

/**
 * 通用的根据条件获取列表接口
 * @param baseUrl
 * @param params
 * @return {Promise<AxiosResponse<any>>}
 */
function list (baseUrl, params) {
  const url = baseUrl + listUrl
  return httpGet(url, params)
}

/**
 * 通用的根据条件获取列表接口
 * @param baseUrl
 * @param params
 * @return {Promise<AxiosResponse<any>>}
 */
function listVo (baseUrl, params) {
  const url = baseUrl + listVoUrl
  return httpGet(url, params)
}

/**
 * 通用的根据Ids获取列表接口
 * @param baseUrl
 * @param params
 * @return {Promise<AxiosResponse<any>>}
 */

function listByIds (baseUrl, params) {
  const url = baseUrl + listByIdsUrl
  return httpGet(url, params)
}

/**
 * 通用的根据Ids删除接口
 * @param baseUrl
 * @param params
 * @return {Promise<AxiosResponse<any>>}
 */
function deleteByIds (baseUrl, params) {
  return httpDelete(baseUrl + deleteByIdsUrl, params)
}

/**
 * 通用的根据Id更新接口
 * @param baseUrl
 * @param params
 * @return {Promise<AxiosResponse<any>>}
 */
function updateById (baseUrl, params) {
  const url = baseUrl + updateByIdUrl
  return httpPut(url, params)
}

/**
 * 通用的插入接口
 * @param baseUrl
 * @param params
 * @return {Promise<AxiosResponse<any>>}
 */
function insert (baseUrl, params) {
  const url = baseUrl + insertUrl
  return httpPost(url, params)
}

// **************************************文件传输************************
const defaultFilename = '未命名文件'

/**
 * 文件下载,该方法适用于后端以blob格式返回的文件(例如导出),也支持url直链
 * @param {string} url - 下载的路径
 * @param {object=} [params] - 请求的参数
 * @param {string=} [filename] - 文件名称,如果文件名需要前端重新命名,那么在这里设置.注意如果是通过直链下载,那么该参数是必须的
 */
function downloadFileStream (url, params, filename) {
  return new Promise((resolve, reject) => {
    commonInstance.get(url, {
      params,
      responseType: 'blob',
    }).then(response => {
      // data是文件的内容
      const {data, headers} = response
      // 创建Blob对象
      const blob = new Blob([data])
      // 从响应头中获取文件名,考虑到乱码的问题,使用decodeURIComponent方法进行转换
      const _filename = filename || decodeURIComponent(headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1')) || defaultFilename
      // 创建a标签用于文件下载
      const link = document.createElement('a')
      // 元素不可见(考虑到a标签是追加在body尾且内容为空,其实不设置也看不见...)
      link.style.display = 'none'
      // 设置跳转的目标
      link.href = URL.createObjectURL(blob)
      // 设置文件名,如果不设置,那么不会触发下载,而是查看blob文件...
      link.download = _filename
      document.body.appendChild(link)
      // 触发下载
      link.click()
      // 释放URL对象
      URL.revokeObjectURL(link.href)
      // 移除元素
      document.body.removeChild(link)
      resolve()
    }).catch((error) => {
      console.error(error)
      reject(error)
    })
  })
}

// 下载文件(url直链)
function downloadFile (url) {
  let _url = /^http/.test(url) ? url : commonInstance.defaults.baseURL + url
  window.open(_url)
}

// 下载前端的静态文件
function downloadStaticFile (path) {
  window.open('static/' + path)
}

// 文件上传功能
function uploadFile (url, param) {
  return httpPostForm(url, param, {
    'Content-type': 'multipart/form-data'
  })
}

// **********************************工具封装******************************
/**
 * 对象转换为formData,一般情况下用不到,如果想发送相关请求,直接使用httpPutForm,httpPostForm即可.
 * @param value
 * @return {FormData}
 */
function toFormData (value) {
  let formData = new FormData()
  Object.keys(value).forEach(key => {
    formData.append(key, value[key])
  })
  return formData
}

export default {
  toFormData,
  httpPost, httpGet, httpPut, httpDelete,
  query, get, getById, list, listByIds, deleteByIds, updateById, insert, listVo,
  downloadFileStream, downloadFile, uploadFile, downloadStaticFile,
  queryUrl, getUrl, getByIdUrl, listUrl, listByIdsUrl, deleteByIdsUrl, updateByIdUrl, insertUrl, listVoUrl,
  httpPutForm, httpPostForm,
  request: commonInstance,
}


